/*
 * =====================================================================================
 *       Filename:  http.h
 *         Author:  MIEN
 *    Description:  解析http数据流
 *           Date:  2016-11-20
 * =====================================================================================
 */

#ifndef HTTP_H
#define HTTP_H

#define HTTP_BUFFER_SIZE (8 * 1024)

static struct {
    int code;
    char *text;
} http_status_list[] = {
    {200, "OK"},
    {400, "Bad Request"},
    {401, "Unauthorized"},
    {404, "Not Found"},
    {405, "Method Not Allowed"},
    {500, "Internal Server Error"},
    {501, "Not Implemented"}
};

/* 当前连接的处理步骤 */
typedef enum http_step {
    READ, WRITE, IDLE
} http_step_t;

/* http实体 */
typedef struct http_entity {
    http_step_t step;               /* 当前步骤 */

    char *bp;                       /* 在缓冲区中移动的指针 */
    char buffer[HTTP_BUFFER_SIZE];  /* 缓冲区 */

    char method[16];                /* GET, POST, HEAD, SUB, UNSUB */
    char uri[256];                  /* 请求的uri */
    char queue[128];                /* 队列名称 */
    char headers[HTTP_BUFFER_SIZE]; /* 头部数据 */
    char body[HTTP_BUFFER_SIZE];    /* 头部之后的BODY数据 */

    int status;                     /* 状态码 */
    int count;                      /* 操作结果记数 */
    int lwritten;                   /* 最后一次输出的数据长度 */

} http_entity_t;

/* 宏定义 */
#define http_get_step(h) ((h)->step)
#define http_set_step(h,s) ((h)->step = (s))
#define http_get_status(h) ((h)->status)
#define http_set_status(h,s) ((h)->status = (s))
#define http_get_count(h) ((h)->count)
#define http_set_count(h,c) ((h)->count = (c))
#define http_set_parser(h,p) ((h)->parser = (p))

/* 从fd读取数据到缓冲区 */
void http_read(http_entity_t *http, int fd);

/* 忽略从fd继续传入的数据 */
void http_discard(http_entity_t *http, int fd);

/* 解析读取到的http数据流 */
void http_parse(http_entity_t *http);

/* 作为客户端发请求 */
void http_request(http_entity_t *http, int fd);

/* 作为服务端做回应 */
void http_response(http_entity_t *http, int fd);

/* 关闭链接 */
void http_close(http_entity_t *http, int fd);

/* 初始http_entity_t */
void http_init(http_entity_t *http);

/* 
 * 获取指定名称的头部数据
 * 比如 http_get_header(http, "Host") 
 */
char *http_get_header(http_entity_t *http, const char *key);

/* 
 * 添加指定名称的头部数据
 * 比如 http_add_header(http, "Host", "www.abc.com") 
 */
void http_add_header(http_entity_t *http, const char *key, const char *value);

/* 获取内容数据 */
char *http_get_body(http_entity_t *http);

/* 重置缓冲区 */
void http_reset_buffer(http_entity_t *http);

/* 附加数据到缓冲区 */
int http_append_to_buffer(http_entity_t *http, const char *str);

#endif /* HTTP_H */
